package hk.linkcredit.walletservice.wallet.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import hk.linkcredit.walletservice.constant.WalletConstants;
import hk.linkcredit.walletservice.utils.StringUtils;
import hk.linkcredit.walletservice.wallet.domain.entity.WalletAmount;
import hk.linkcredit.walletservice.wallet.domain.vo.WalletAccountInfo;
import hk.linkcredit.walletservice.wallet.mapper.WalletAmountMapper;
import hk.linkcredit.walletservice.wallet.service.WalletAmountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 钱包金额表 服务实现类
 * </p>
 *
 * @author LinkCredit
 * @since 2022-06-10 01:23:44
 */
@Slf4j
@Service
public class WalletAmountServiceImpl extends ServiceImpl<WalletAmountMapper, WalletAmount> implements WalletAmountService {

    @Autowired
    WalletAmountMapper walletAmountMapper;

    @Override
    public void freezeWalletAmt(String walletType, BigDecimal freezeAmt, WalletAccountInfo walletAccount) {
        log.info("开始冻结钱包金额 >>> walletType = {}，freezeAmt = {}", walletType, freezeAmt);

        Long id = getAccountId(walletType, walletAccount);

        UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
        wrapper.setSql("frozen_amount = frozen_amount + " + freezeAmt)
                .eq("id", id);
        this.update(wrapper);

        log.info("完成钱包金额冻结 >>> ");
    }

    @Override
    public void unfreezeWalletAmount(WalletAmount walletAmount) {
        log.info("开始解冻钱包金额 >>> walletAmount = {}", walletAmount);

        UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
        wrapper.setSql("frozen_amount = if(frozen_amount - " + walletAmount.getFrozenAmount()
                        + " < 0, 0, " + "(frozen_amount -" + walletAmount.getFrozenAmount() + "))")
                .eq("cust_no", walletAmount.getCustNo())
                .eq("wallet_type", walletAmount.getWalletType());

        this.update(wrapper);

        log.info("完成钱包金额解冻 >>> ");
    }

    @Override
    public void updateWalletAccountAmount(String walletType, BigDecimal amount, WalletAccountInfo walletAccountInfo) {
        log.info("开始增加钱包金额 >>> walletType = {}，amount  = {}，walletAccountInfo = {}", walletType, amount, walletAccountInfo);

        Long id = getAccountId(walletType, walletAccountInfo);

        UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
        wrapper.setSql("amount = amount + " + amount)
                .eq("id", id);
        this.update(wrapper);

        log.info("结束增加钱包金额 >>> ");
    }

    @Override
    public void freezeWalletAmt(JSONObject repaySplitAmt, WalletAccountInfo walletAccount) {
        log.info("开始冻结钱包金额 >>> repaySplitAmt = {}，walletAccount = {}", repaySplitAmt, walletAccount);

        BigDecimal balanceAmt = repaySplitAmt.getBigDecimal("balanceAmt");
        if (balanceAmt.compareTo(BigDecimal.ZERO) > 0) {
            UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
            wrapper.setSql("frozen_amount = frozen_amount + " + balanceAmt)
                    .eq("id", walletAccount.getWalletBalanceId());
            this.update(wrapper);
        }

        BigDecimal bonusAmt = repaySplitAmt.getBigDecimal("bonusAmt");
        if (bonusAmt.compareTo(BigDecimal.ZERO) > 0) {
            UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
            wrapper.setSql("frozen_amount = frozen_amount + " + bonusAmt)
                    .eq("id", walletAccount.getWalletBonusId());
            this.update(wrapper);
        }

        log.info("完成钱包金额冻结 >>> ");
    }

    @Override
    public void deductionWalletAmount(WalletAmount walletAmount) {
        log.info("开始扣减钱包金额 >>> walletAmount = {}", walletAmount);

        UpdateWrapper<WalletAmount> wrapper = Wrappers.update();
        wrapper.setSql("frozen_amount = if(frozen_amount - " + walletAmount.getFrozenAmount()
                        + " < 0, 0, " + "(frozen_amount -" + walletAmount.getFrozenAmount() + ")), "
                        + "amount = if(amount - " + walletAmount.getFrozenAmount()
                        + " < 0, 0, " + "(amount - " + walletAmount.getFrozenAmount() + "))")
                .eq("cust_no", walletAmount.getCustNo())
                .eq("wallet_type", walletAmount.getWalletType());

        this.update(wrapper);

        log.info("完成钱包金额扣减 >>> ");
    }

    @Override
    public List<String> getCustomersWithBalance() {
        return walletAmountMapper.getCustomersWithBalance();
    }

    private Long getAccountId(String walletType, WalletAccountInfo walletAccount) {
        Long id = 0L;
        if (StringUtils.equals(WalletConstants.WALLET_ORDER_TYPE_BALANCE, walletType)) {
            id = walletAccount.getWalletBalanceId();
        } else if (StringUtils.equals(WalletConstants.WALLET_ORDER_TYPE_BONUS, walletType)) {
            id = walletAccount.getWalletBonusId();
        }
        return id;
    }
}
